const WebSocket = require('ws');

class NotificationHandler {
    constructor() {
        this.notificationWss = new WebSocket.Server({ noServer: true });
        this.notificationTypes = new Map(); // 存储不同类型的通知订阅者
        this.setupNotificationHandler();
        this.startNotificationPublishing();
    }

    setupNotificationHandler() {
        this.notificationWss.on('connection', (ws, request) => {
            console.log('通知客户端已连接');
            ws.wsType = 'notification';
            ws.notificationTypes = new Set(['all']); // 默认订阅所有通知

            ws.on('message', (message) => {
                try {
                    const data = JSON.parse(message);
                    this.handleNotificationMessage(ws, data);
                } catch (error) {
                    ws.send(JSON.stringify({ type: 'error', message: '消息格式错误' }));
                }
            });

            ws.on('close', (code, reason) => {
                console.log(`通知客户端断开连接: ${code} - ${reason}`);
                this.handleClientDisconnect(ws);
            });

            ws.send(JSON.stringify({ type: 'welcome', message: '通知服务已连接' }));
        });
    }

    handleNotificationMessage(ws, data) {
        switch (data.type) {
            case 'subscribe':
                this.subscribeToNotifications(ws, data.types);
                break;
            case 'unsubscribe':
                this.unsubscribeFromNotifications(ws, data.types);
                break;
            case 'getSubscriptions':
                this.sendSubscriptions(ws);
                break;
            case 'sendNotification':
                this.sendCustomNotification(ws, data);
                break;
            default:
                ws.send(JSON.stringify({ type: 'error', message: '未知的通知消息类型' }));
        }
    }

    subscribeToNotifications(ws, types = ['all']) {
        ws.notificationTypes.clear();
        
        types.forEach(type => {
            ws.notificationTypes.add(type);
            
            if (!this.notificationTypes.has(type)) {
                this.notificationTypes.set(type, new Set());
            }
            this.notificationTypes.get(type).add(ws);
        });

        ws.send(JSON.stringify({
            type: 'subscribed',
            notificationTypes: Array.from(ws.notificationTypes),
            message: `已订阅通知类型: ${types.join(', ')}`
        }));
    }

    unsubscribeFromNotifications(ws, types = ['all']) {
        types.forEach(type => {
            ws.notificationTypes.delete(type);
            
            if (this.notificationTypes.has(type)) {
                this.notificationTypes.get(type).delete(ws);
            }
        });

        ws.send(JSON.stringify({
            type: 'unsubscribed',
            notificationTypes: Array.from(ws.notificationTypes),
            message: `已取消订阅通知类型: ${types.join(', ')}`
        }));
    }

    sendSubscriptions(ws) {
        ws.send(JSON.stringify({
            type: 'subscriptions',
            notificationTypes: Array.from(ws.notificationTypes)
        }));
    }

    sendCustomNotification(ws, data) {
        const notification = {
            type: 'customNotification',
            level: data.level || 'info',
            title: data.title || '自定义通知',
            message: data.message,
            timestamp: new Date().toISOString(),
            sender: data.sender || '系统'
        };

        this.broadcastNotification(notification, data.targetTypes);
    }

    handleClientDisconnect(ws) {
        // 清理订阅
        ws.notificationTypes.forEach(type => {
            if (this.notificationTypes.has(type)) {
                this.notificationTypes.get(type).delete(ws);
            }
        });
    }

    startNotificationPublishing() {
        // 定时发送系统通知
        setInterval(() => {
            this.broadcastNotification({
                type: 'notification',
                level: 'info',
                title: '系统通知',
                message: '这是一条定时系统通知',
                timestamp: new Date().toISOString()
            });
        }, 10000);

        // 定时发送警告通知
        setInterval(() => {
            this.broadcastNotification({
                type: 'notification',
                level: 'warning',
                title: '系统警告',
                message: '系统资源使用率较高',
                timestamp: new Date().toISOString()
            }, ['warning', 'all']);
        }, 15000);
    }

    broadcastNotification(notification, targetTypes = ['all']) {
        const targetClients = new Set();

        targetTypes.forEach(type => {
            if (this.notificationTypes.has(type)) {
                this.notificationTypes.get(type).forEach(ws => {
                    targetClients.add(ws);
                });
            }
        });

        targetClients.forEach(ws => {
            if (ws.readyState === WebSocket.OPEN) {
                ws.send(JSON.stringify(notification));
            }
        });
    }

    getServer() {
        return this.notificationWss;
    }
}

module.exports = NotificationHandler;